﻿' FileExtractor.vb - 修改版
Imports System.IO
Imports System.Text
Imports System.Text.RegularExpressions
Imports DocumentFormat.OpenXml.Packaging
Imports DocumentFormat.OpenXml.Spreadsheet
Imports DocumentFormat.OpenXml.Presentation
Imports A = DocumentFormat.OpenXml.Drawing
Imports System.Runtime.InteropServices
Imports Microsoft.Office.Interop.Word
Imports Microsoft.Office.Interop.Excel
Imports Microsoft.Office.Interop.PowerPoint
Imports Microsoft.Office.Core
Imports UglyToad.PdfPig
Imports UglyToad.PdfPig.DocumentLayoutAnalysis.TextExtractor

Public Class FileExtractor
    Public ReadOnly _ocrProcessor As OcrProcessor

    Public Sub New()
        ' 初始化OCR处理器
        _ocrProcessor = New OcrProcessor()
    End Sub

    ' 提取文本文件内容
    Public Function ExtractTextContent(filePath As String) As String
        Try
            If Not File.Exists(filePath) Then
                Return String.Empty
            End If

            Dim extension As String = Path.GetExtension(filePath).ToLower()

            Select Case extension
                Case ".txt", ".log", ".md", ".csv", ".json", ".xml", ".html", ".htm", ".css", ".js", ".vb", ".cs", ".sql"
                    Return File.ReadAllText(filePath, GetEncoding(filePath))

                Case ".docx", ".xlsx", ".pptx"
                    Return ExtractOfficeContent(filePath)

                Case ".doc", ".xls", ".ppt"
                    ' 处理旧版Office文件
                    Return ExtractLegacyOfficeContent(filePath)

                Case ".pdf"
                    Return ExtractPdfContentWithPdfPig(filePath)

                Case Else
                    ' 对于图片文件，尝试执行OCR
                    If _ocrProcessor.IsSupportedImageFile(filePath) Then
                        Return ExtractImageText(filePath)
                    ElseIf IsTextFile(filePath) Then
                        Return File.ReadAllText(filePath, GetEncoding(filePath))
                    End If
                    Return String.Empty
            End Select

        Catch ex As Exception
            Logger.Log($"提取文件内容错误: {ex.Message}")
            Return String.Empty
        End Try
    End Function

    ' 从图片中提取文本
    Private Function ExtractImageText(imagePath As String) As String
        Try
            'Dim text = _ocrProcessor.ExtractTextFromImage(imagePath)
            Dim text = _ocrProcessor.ExtractTextFromImageWithTimeout(imagePath, 120000) ' 2分钟超时
            If Not String.IsNullOrEmpty(text) Then
                ' 添加一个标记，表明这是从图片中提取的文本
                Return $"[图片OCR文本] {text}"
            End If
            Return String.Empty
        Catch ex As Exception
            Logger.Log($"OCR错误: {ex.Message}")
            Return String.Empty
        End Try
    End Function

    ' 判断是否为文本文件
    Private Function IsTextFile(filePath As String) As Boolean
        Try
            Using stream As New FileStream(filePath, FileMode.Open, FileAccess.Read)
                Dim buffer(4096) As Byte
                Dim bytesRead As Integer = stream.Read(buffer, 0, buffer.Length)

                ' 检查是否包含空字节 (通常表示二进制文件)
                For i As Integer = 0 To bytesRead - 1
                    If buffer(i) = 0 Then
                        Return False
                    End If
                Next

                Return True
            End Using
        Catch ex As Exception
            Return False
        End Try
    End Function

    ' 获取文件编码
    Private Function GetEncoding(filePath As String) As Encoding
        Try
            Using reader As New StreamReader(filePath, Encoding.Default, True)
                reader.Peek() ' 触发检测
                Return reader.CurrentEncoding
            End Using
        Catch ex As Exception
            Return Encoding.UTF8
        End Try
    End Function


    ''' <summary>
    ''' 提取Office文档内容
    ''' </summary>
    ''' <param name="filePath">文件路径</param>
    ''' <returns>提取的文本内容</returns>
    Private Function ExtractOfficeContent(filePath As String) As String
        If Not File.Exists(filePath) Then
            Return String.Empty
        End If

        Try
            Dim extension As String = Path.GetExtension(filePath).ToLower()

            Select Case extension
                Case ".docx"
                    Return ExtractWordContent(filePath)

                Case ".xlsx"
                    Return ExtractExcelContent(filePath)

                Case ".pptx"
                    Return ExtractPowerPointContent(filePath)

                Case Else
                    Return $"[不支持的Office文档类型: {extension}]"
            End Select
        Catch ex As Exception
            ' 记录错误但不中断程序流程
            Logger.Log($"提取Office内容出错: {filePath}, 错误: {ex.Message}")
            Return $"[Office文档提取错误: {Path.GetFileName(filePath)}]"
        End Try
    End Function

    ''' <summary>
    ''' 提取旧版 Office 文档内容
    ''' </summary>
    ''' <param name="filePath">文件路径</param>
    ''' <returns>提取的文本内容</returns>
    Private Function ExtractLegacyOfficeContent(filePath As String) As String
        If Not File.Exists(filePath) Then
            Return String.Empty
        End If

        Dim extension As String = Path.GetExtension(filePath).ToLower()

        Try
            Select Case extension
                Case ".doc"
                    Return ExtractWordLegacyContent(filePath)

                Case ".xls"
                    Return ExtractExcelLegacyContent(filePath)

                Case ".ppt"
                    Return ExtractPowerPointLegacyContent(filePath)

                Case Else
                    Return $"[不支持的旧版Office文档类型: {extension}]"
            End Select
        Catch ex As Exception
            Logger.Log($"提取旧版Office内容出错: {filePath}, 错误: {ex.Message}")
            Return $"[旧版Office文档提取错误: {Path.GetFileName(filePath)}]"
        End Try
    End Function

    ''' <summary>
    ''' 提取旧版 Word 文档内容
    ''' </summary>
    Private Function ExtractWordLegacyContent(filePath As String) As String
        Dim wordApp As Microsoft.Office.Interop.Word.Application = Nothing
        Dim wordDoc As Microsoft.Office.Interop.Word.Document = Nothing
        Dim text As New StringBuilder()

        Try
            ' 创建 Word 应用程序实例
            wordApp = New Microsoft.Office.Interop.Word.Application()
            wordApp.Visible = False

            ' 打开文档
            wordDoc = wordApp.Documents.Open(filePath, ReadOnly:=True, NoEncodingDialog:=True)

            ' 提取文本内容
            text.Append(wordDoc.Content.Text)

            ' 提取文档属性
            Try
                If wordDoc.BuiltInDocumentProperties IsNot Nothing Then
                    Dim props = wordDoc.BuiltInDocumentProperties

                    Try
                        If props.Item("Title").Value IsNot Nothing Then
                            text.AppendLine("标题: " & props.Item("Title").Value.ToString())
                        End If
                    Catch
                        ' 忽略属性访问错误
                    End Try

                    Try
                        If props.Item("Subject").Value IsNot Nothing Then
                            text.AppendLine("主题: " & props.Item("Subject").Value.ToString())
                        End If
                    Catch
                        ' 忽略属性访问错误
                    End Try

                    Try
                        If props.Item("Keywords").Value IsNot Nothing Then
                            text.AppendLine("关键词: " & props.Item("Keywords").Value.ToString())
                        End If
                    Catch
                        ' 忽略属性访问错误
                    End Try

                    Try
                        If props.Item("Comments").Value IsNot Nothing Then
                            text.AppendLine("备注: " & props.Item("Comments").Value.ToString())
                        End If
                    Catch
                        ' 忽略属性访问错误
                    End Try

                    Try
                        If props.Item("Category").Value IsNot Nothing Then
                            text.AppendLine("类别: " & props.Item("Category").Value.ToString())
                        End If
                    Catch
                        ' 忽略属性访问错误
                    End Try
                End If
            Catch ex As Exception
                ' 忽略属性提取错误
                Logger.Log("提取Word文档属性错误: " & ex.Message)
            End Try

            Return CleanText(text.ToString())
        Catch ex As Exception
            Logger.Log("提取Word文档内容错误: " & ex.Message)
            Return $"[Word文档: {Path.GetFileName(filePath)}]"
        Finally
            ' 清理资源
            If wordDoc IsNot Nothing Then
                Try
                    wordDoc.Close(SaveChanges:=False)
                    Marshal.ReleaseComObject(wordDoc)
                Catch
                    ' 忽略释放错误
                End Try
                wordDoc = Nothing
            End If

            If wordApp IsNot Nothing Then
                Try
                    wordApp.Quit()
                    Marshal.ReleaseComObject(wordApp)
                Catch
                    ' 忽略释放错误
                End Try
                wordApp = Nothing
            End If

            ' 强制垃圾回收
            GC.Collect()
            GC.WaitForPendingFinalizers()
        End Try
    End Function

    ''' <summary>
    ''' 提取旧版 Excel 文档内容
    ''' </summary>
    Private Function ExtractExcelLegacyContent(filePath As String) As String
        Dim excelApp As Microsoft.Office.Interop.Excel.Application = Nothing
        Dim workbook As Microsoft.Office.Interop.Excel.Workbook = Nothing
        Dim text As New StringBuilder()

        Try
            ' 创建 Excel 应用程序实例
            excelApp = New Microsoft.Office.Interop.Excel.Application()
            excelApp.Visible = False
            excelApp.DisplayAlerts = False

            ' 打开工作簿
            workbook = excelApp.Workbooks.Open(filePath, ReadOnly:=True)

            ' 处理每个工作表
            For Each worksheet As Microsoft.Office.Interop.Excel.Worksheet In workbook.Worksheets
                text.AppendLine("工作表: " & worksheet.Name)

                ' 获取使用范围
                Dim usedRange As Microsoft.Office.Interop.Excel.Range = worksheet.UsedRange

                ' 处理每个行
                Dim rowCount As Integer = usedRange.Rows.Count
                Dim colCount As Integer = usedRange.Columns.Count

                For rowIdx As Integer = 1 To Math.Min(rowCount, 1000) ' 限制行数以提高性能
                    Dim rowText As New StringBuilder()

                    ' 处理每个单元格
                    For colIdx As Integer = 1 To Math.Min(colCount, 100) ' 限制列数以提高性能
                        Dim cell As Microsoft.Office.Interop.Excel.Range = usedRange.Cells(rowIdx, colIdx)

                        If cell IsNot Nothing AndAlso cell.Value IsNot Nothing Then
                            rowText.Append(cell.Value.ToString() & " ")
                        End If
                    Next

                    If rowText.Length > 0 Then
                        text.AppendLine(rowText.ToString().Trim())
                    End If
                Next

                text.AppendLine() ' 工作表之间添加空行
            Next

            ' 提取文档属性
            Try
                If workbook.BuiltinDocumentProperties IsNot Nothing Then
                    Dim props = workbook.BuiltinDocumentProperties

                    Try
                        If props.Item("Title").Value IsNot Nothing Then
                            text.AppendLine("标题: " & props.Item("Title").Value.ToString())
                        End If
                    Catch
                        ' 忽略属性访问错误
                    End Try

                    Try
                        If props.Item("Subject").Value IsNot Nothing Then
                            text.AppendLine("主题: " & props.Item("Subject").Value.ToString())
                        End If
                    Catch
                        ' 忽略属性访问错误
                    End Try

                    Try
                        If props.Item("Keywords").Value IsNot Nothing Then
                            text.AppendLine("关键词: " & props.Item("Keywords").Value.ToString())
                        End If
                    Catch
                        ' 忽略属性访问错误
                    End Try

                    Try
                        If props.Item("Comments").Value IsNot Nothing Then
                            text.AppendLine("备注: " & props.Item("Comments").Value.ToString())
                        End If
                    Catch
                        ' 忽略属性访问错误
                    End Try

                    Try
                        If props.Item("Category").Value IsNot Nothing Then
                            text.AppendLine("类别: " & props.Item("Category").Value.ToString())
                        End If
                    Catch
                        ' 忽略属性访问错误
                    End Try
                End If
            Catch ex As Exception
                ' 忽略属性提取错误
                Logger.Log("提取Excel文档属性错误: " & ex.Message)
            End Try

            Return CleanText(text.ToString())
        Catch ex As Exception
            Logger.Log("提取Excel文档内容错误: " & ex.Message)
            Return $"[Excel文档: {Path.GetFileName(filePath)}]"
        Finally
            ' 清理资源
            If workbook IsNot Nothing Then
                Try
                    workbook.Close(SaveChanges:=False)
                    Marshal.ReleaseComObject(workbook)
                Catch
                    ' 忽略释放错误
                End Try
                workbook = Nothing
            End If

            If excelApp IsNot Nothing Then
                Try
                    excelApp.Quit()
                    Marshal.ReleaseComObject(excelApp)
                Catch
                    ' 忽略释放错误
                End Try
                excelApp = Nothing
            End If

            ' 强制垃圾回收
            GC.Collect()
            GC.WaitForPendingFinalizers()
        End Try
    End Function

    ''' <summary>
    ''' 提取旧版 PowerPoint 文档内容
    ''' </summary>
    Private Function ExtractPowerPointLegacyContent(filePath As String) As String
        Dim pptApp As Microsoft.Office.Interop.PowerPoint.Application = Nothing
        Dim presentation As Microsoft.Office.Interop.PowerPoint.Presentation = Nothing
        Dim text As New StringBuilder()

        Try
            ' 创建 PowerPoint 应用程序实例
            pptApp = New Microsoft.Office.Interop.PowerPoint.Application()
            pptApp.Visible = Microsoft.Office.Core.MsoTriState.msoFalse

            ' 打开演示文稿
            presentation = pptApp.Presentations.Open(filePath, WithWindow:=Microsoft.Office.Core.MsoTriState.msoFalse)

            ' 处理每张幻灯片
            Dim slideCount As Integer = presentation.Slides.Count

            For slideIdx As Integer = 1 To slideCount
                Dim slide As Microsoft.Office.Interop.PowerPoint.Slide = presentation.Slides(slideIdx)

                text.AppendLine($"幻灯片 {slideIdx}:")

                ' 提取幻灯片中的形状文本
                For Each shape As Microsoft.Office.Interop.PowerPoint.Shape In slide.Shapes
                    If shape.HasTextFrame = Microsoft.Office.Core.MsoTriState.msoTrue Then
                        If shape.TextFrame.HasText = Microsoft.Office.Core.MsoTriState.msoTrue Then
                            text.AppendLine(shape.TextFrame.TextRange.Text)
                        End If
                    End If
                Next

                ' 提取幻灯片备注
                If slide.HasNotesPage = Microsoft.Office.Core.MsoTriState.msoTrue Then
                    Dim notesPage As Microsoft.Office.Interop.PowerPoint.SlideRange = slide.NotesPage

                    For Each shape As Microsoft.Office.Interop.PowerPoint.Shape In notesPage.Shapes
                        If shape.HasTextFrame = Microsoft.Office.Core.MsoTriState.msoTrue Then
                            If shape.TextFrame.HasText = Microsoft.Office.Core.MsoTriState.msoTrue Then
                                Dim noteText As String = shape.TextFrame.TextRange.Text
                                If Not String.IsNullOrEmpty(noteText) Then
                                    text.AppendLine("备注: " & noteText)
                                End If
                            End If
                        End If
                    Next
                End If

                text.AppendLine() ' 幻灯片之间添加空行
            Next

            ' 提取文档属性
            Try
                If presentation.BuiltInDocumentProperties IsNot Nothing Then
                    Dim props = presentation.BuiltInDocumentProperties

                    Try
                        If props.Item("Title") IsNot Nothing Then
                            text.AppendLine("标题: " & props.Item("Title").Value.ToString())
                        End If
                    Catch
                        ' 忽略属性访问错误
                    End Try

                    Try
                        If props.Item("Subject") IsNot Nothing Then
                            text.AppendLine("主题: " & props.Item("Subject").Value.ToString())
                        End If
                    Catch
                        ' 忽略属性访问错误
                    End Try

                    Try
                        If props.Item("Keywords") IsNot Nothing Then
                            text.AppendLine("关键词: " & props.Item("Keywords").Value.ToString())
                        End If
                    Catch
                        ' 忽略属性访问错误
                    End Try

                    Try
                        If props.Item("Comments") IsNot Nothing Then
                            text.AppendLine("备注: " & props.Item("Comments").Value.ToString())
                        End If
                    Catch
                        ' 忽略属性访问错误
                    End Try

                    Try
                        If props.Item("Category") IsNot Nothing Then
                            text.AppendLine("类别: " & props.Item("Category").Value.ToString())
                        End If
                    Catch
                        ' 忽略属性访问错误
                    End Try
                End If
            Catch ex As Exception
                ' 忽略属性提取错误
                Logger.Log("提取PowerPoint文档属性错误: " & ex.Message)
            End Try

            Return CleanText(text.ToString())
        Catch ex As Exception
            Logger.Log("提取PowerPoint文档内容错误: " & ex.Message)
            Return $"[PowerPoint文档: {Path.GetFileName(filePath)}]"
        Finally
            ' 清理资源
            If presentation IsNot Nothing Then
                Try
                    presentation.Close()
                    Marshal.ReleaseComObject(presentation)
                Catch
                    ' 忽略释放错误
                End Try
                presentation = Nothing
            End If

            If pptApp IsNot Nothing Then
                Try
                    pptApp.Quit()
                    Marshal.ReleaseComObject(pptApp)
                Catch
                    ' 忽略释放错误
                End Try
                pptApp = Nothing
            End If

            ' 强制垃圾回收
            GC.Collect()
            GC.WaitForPendingFinalizers()
        End Try
    End Function


    ''' <summary>
    ''' 提取Word文档内容
    ''' </summary>
    Private Function ExtractWordContent(filePath As String) As String
        Dim text As New StringBuilder()

        Try
            Using wordDoc As WordprocessingDocument = WordprocessingDocument.Open(filePath, False)
                ' 提取文档主体文本
                If wordDoc.MainDocumentPart IsNot Nothing Then
                    text.Append(wordDoc.MainDocumentPart.Document.InnerText)
                End If

                ' 提取页眉页脚
                If wordDoc.MainDocumentPart.HeaderParts IsNot Nothing Then
                    For Each header In wordDoc.MainDocumentPart.HeaderParts
                        text.Append(header.Header.InnerText)
                    Next
                End If

                If wordDoc.MainDocumentPart.FooterParts IsNot Nothing Then
                    For Each footer In wordDoc.MainDocumentPart.FooterParts
                        text.Append(footer.Footer.InnerText)
                    Next
                End If

                ' 提取批注
                If wordDoc.MainDocumentPart.WordprocessingCommentsPart IsNot Nothing Then
                    Dim comments = wordDoc.MainDocumentPart.WordprocessingCommentsPart.Comments
                    If comments IsNot Nothing Then
                        text.Append(comments.InnerText)
                    End If
                End If

                ' 尝试提取文档属性
                If wordDoc.PackageProperties IsNot Nothing Then
                    With wordDoc.PackageProperties
                        If Not String.IsNullOrEmpty(.Title) Then
                            text.AppendLine("标题: " & .Title)
                        End If

                        If Not String.IsNullOrEmpty(.Subject) Then
                            text.AppendLine("主题: " & .Subject)
                        End If

                        If Not String.IsNullOrEmpty(.Keywords) Then
                            text.AppendLine("关键词: " & .Keywords)
                        End If

                        If Not String.IsNullOrEmpty(.Description) Then
                            text.AppendLine("描述: " & .Description)
                        End If

                        If Not String.IsNullOrEmpty(.Category) Then
                            text.AppendLine("类别: " & .Category)
                        End If
                    End With
                End If
            End Using

            Return CleanText(text.ToString())
        Catch ex As Exception
            Logger.Log($"Word文档内容提取错误: {ex.Message}")
            Return $"[Word文档: {Path.GetFileName(filePath)}]"
        End Try
    End Function

    ''' <summary>
    ''' 提取Excel文档内容
    ''' </summary>
    Private Function ExtractExcelContent(filePath As String) As String
        Dim text As New StringBuilder()

        Try
            Using spreadsheetDocument As SpreadsheetDocument = SpreadsheetDocument.Open(filePath, False)
                Dim workbookPart As WorkbookPart = spreadsheetDocument.WorkbookPart

                ' 获取共享字符串表
                Dim sharedStrings As SharedStringTable = Nothing
                If workbookPart.SharedStringTablePart IsNot Nothing Then
                    sharedStrings = workbookPart.SharedStringTablePart.SharedStringTable
                End If

                Dim sheets = workbookPart.Workbook.Descendants(Of Sheet)()

                ' 提取各工作表内容
                For Each sheet In sheets
                    text.AppendLine("工作表: " & sheet.Name.ToString)

                    ' 获取当前工作表的数据
                    Dim worksheetPart As WorksheetPart = DirectCast(workbookPart.GetPartById(sheet.Id), WorksheetPart)
                    Dim worksheet As DocumentFormat.OpenXml.Spreadsheet.Worksheet = worksheetPart.Worksheet
                    Dim sheetData As SheetData = worksheet.Elements(Of SheetData)().First()

                    ' 提取单元格内容
                    For Each row As DocumentFormat.OpenXml.Spreadsheet.Row In sheetData.Elements(Of DocumentFormat.OpenXml.Spreadsheet.Row)()
                        Dim rowText As New StringBuilder()

                        For Each cell As DocumentFormat.OpenXml.Spreadsheet.Cell In row.Elements(Of DocumentFormat.OpenXml.Spreadsheet.Cell)()
                            Dim cellText As String = String.Empty

                            ' 根据单元格类型获取值
                            If cell.DataType IsNot Nothing AndAlso cell.DataType.Value = CellValues.SharedString Then
                                ' 共享字符串
                                If sharedStrings IsNot Nothing AndAlso cell.CellValue IsNot Nothing AndAlso Not String.IsNullOrEmpty(cell.CellValue.Text) Then
                                    Dim ssid As Integer = Integer.Parse(cell.CellValue.Text)
                                    cellText = sharedStrings.ElementAt(ssid).InnerText
                                End If
                            ElseIf cell.CellValue IsNot Nothing Then
                                ' 直接值
                                cellText = cell.CellValue.Text
                            End If

                            If Not String.IsNullOrEmpty(cellText) Then
                                rowText.Append(cellText & " ")
                            End If
                        Next

                        If rowText.Length > 0 Then
                            text.AppendLine(rowText.ToString())
                        End If
                    Next

                    text.AppendLine() ' 工作表之间增加空行
                Next

                ' 尝试提取文档属性
                If spreadsheetDocument.PackageProperties IsNot Nothing Then
                    With spreadsheetDocument.PackageProperties
                        If Not String.IsNullOrEmpty(.Title) Then
                            text.AppendLine("标题: " & .Title)
                        End If

                        If Not String.IsNullOrEmpty(.Subject) Then
                            text.AppendLine("主题: " & .Subject)
                        End If

                        If Not String.IsNullOrEmpty(.Keywords) Then
                            text.AppendLine("关键词: " & .Keywords)
                        End If

                        If Not String.IsNullOrEmpty(.Description) Then
                            text.AppendLine("描述: " & .Description)
                        End If

                        If Not String.IsNullOrEmpty(.Category) Then
                            text.AppendLine("类别: " & .Category)
                        End If
                    End With
                End If
            End Using

            Return CleanText(text.ToString())
        Catch ex As Exception
            Logger.Log($"Excel文档内容提取错误: {ex.Message}")
            Return $"[Excel文档: {Path.GetFileName(filePath)}]"
        End Try
    End Function

    ''' <summary>
    ''' 提取PowerPoint文档内容
    ''' </summary>
    Private Function ExtractPowerPointContent(filePath As String) As String
        Dim text As New StringBuilder()

        Try
            Using presentationDocument As PresentationDocument = PresentationDocument.Open(filePath, False)
                Dim presentationPart As PresentationPart = presentationDocument.PresentationPart

                If presentationPart IsNot Nothing AndAlso presentationPart.Presentation IsNot Nothing Then
                    ' 获取所有幻灯片
                    Dim slideIds = presentationPart.Presentation.SlideIdList

                    If slideIds IsNot Nothing Then
                        Dim slideCounter As Integer = 1

                        ' 处理每一张幻灯片
                        For Each slideId In slideIds.Elements(Of SlideId)()
                            Dim slidePart As SlidePart = DirectCast(presentationPart.GetPartById(slideId.RelationshipId), SlidePart)

                            text.AppendLine($"幻灯片 {slideCounter}:")

                            ' 提取幻灯片中的文本
                            Dim paragraphs = slidePart.Slide.Descendants(Of A.Paragraph)()
                            For Each paragraph In paragraphs
                                For Each textElement In paragraph.Descendants(Of A.Text)()
                                    text.AppendLine(textElement.Text)
                                Next
                            Next

                            ' 提取幻灯片注释
                            If slidePart.NotesSlidePart IsNot Nothing Then
                                text.AppendLine("注释:")
                                Dim notesParagraphs = slidePart.NotesSlidePart.NotesSlide.Descendants(Of A.Paragraph)()
                                For Each paragraph In notesParagraphs
                                    For Each textElement In paragraph.Descendants(Of A.Text)()
                                        text.AppendLine(textElement.Text)
                                    Next
                                Next
                            End If

                            text.AppendLine() ' 每张幻灯片之间添加空行
                            slideCounter += 1
                        Next
                    End If

                    ' 尝试提取文档属性
                    If presentationDocument.PackageProperties IsNot Nothing Then
                        With presentationDocument.PackageProperties
                            If Not String.IsNullOrEmpty(.Title) Then
                                text.AppendLine("标题: " & .Title)
                            End If

                            If Not String.IsNullOrEmpty(.Subject) Then
                                text.AppendLine("主题: " & .Subject)
                            End If

                            If Not String.IsNullOrEmpty(.Keywords) Then
                                text.AppendLine("关键词: " & .Keywords)
                            End If

                            If Not String.IsNullOrEmpty(.Description) Then
                                text.AppendLine("描述: " & .Description)
                            End If

                            If Not String.IsNullOrEmpty(.Category) Then
                                text.AppendLine("类别: " & .Category)
                            End If
                        End With
                    End If
                End If
            End Using

            Return CleanText(text.ToString())
        Catch ex As Exception
            Logger.Log($"PowerPoint文档内容提取错误: {ex.Message}")
            Return $"[PowerPoint文档: {Path.GetFileName(filePath)}]"
        End Try
    End Function

    ''' <summary>
    ''' 清理提取的文本内容
    ''' </summary>
    Private Function CleanText(text As String) As String
        If String.IsNullOrEmpty(text) Then
            Return String.Empty
        End If

        ' 替换多个连续空白字符为单个空格
        Dim cleanedText As String = System.Text.RegularExpressions.Regex.Replace(text, "\s+", " ")

        ' 替换多个连续换行符为单个换行符
        cleanedText = System.Text.RegularExpressions.Regex.Replace(cleanedText, "(\r\n|\n|\r){2,}", Environment.NewLine)

        ' 去除可能存在的无用控制字符
        cleanedText = System.Text.RegularExpressions.Regex.Replace(cleanedText, "[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]", "")

        Return cleanedText.Trim()
    End Function

    ''' <summary>
    ''' 使用 PdfPig 提取PDF文档内容
    ''' </summary>
    Private Function ExtractPdfContentWithPdfPig(filePath As String) As String
        If Not File.Exists(filePath) Then
            Return String.Empty
        End If

        Dim text As New StringBuilder()

        Try
            Using document As PdfDocument = PdfDocument.Open(filePath)
                ' 提取文档信息
                If document.Information IsNot Nothing Then
                    If Not String.IsNullOrEmpty(document.Information.Title) Then
                        text.AppendLine("标题: " & document.Information.Title)
                    End If

                    If Not String.IsNullOrEmpty(document.Information.Subject) Then
                        text.AppendLine("主题: " & document.Information.Subject)
                    End If

                    If Not String.IsNullOrEmpty(document.Information.Keywords) Then
                        text.AppendLine("关键词: " & document.Information.Keywords)
                    End If

                    If Not String.IsNullOrEmpty(document.Information.Author) Then
                        text.AppendLine("作者: " & document.Information.Author)
                    End If

                    text.AppendLine() ' 添加空行
                End If

                ' 提取每页内容
                For i As Integer = 0 To document.NumberOfPages - 1
                    Dim pageNumber As Integer = i + 1
                    Dim page = document.GetPage(pageNumber)

                    text.AppendLine("--- 第 " & pageNumber & " 页 ---")

                    ' 使用简单文本提取
                    Dim pageText = ContentOrderTextExtractor.GetText(page)
                    text.AppendLine(pageText)

                    ' 如果简单提取结果为空，尝试使用替代方法
                    If String.IsNullOrWhiteSpace(pageText) Then
                        Dim alternativeText = String.Join(" ", page.Letters.Select(Function(l) l.Value))
                        text.AppendLine(alternativeText)
                    End If

                    text.AppendLine()
                Next
            End Using

            Return CleanPdfText(text.ToString())
        Catch ex As Exception
            Logger.Log($"PDF文本提取错误: {filePath}, 错误: {ex.Message}")
            Return $"[PDF文档: {Path.GetFileName(filePath)}]"
        End Try
    End Function

    ''' <summary>
    ''' 清理PDF提取的文本
    ''' </summary>
    Private Function CleanPdfText(text As String) As String
        If String.IsNullOrEmpty(text) Then
            Return String.Empty
        End If

        ' 替换连续空白
        Dim cleanedText As String = System.Text.RegularExpressions.Regex.Replace(text, "\s+", " ")

        ' 替换重复的换行符
        cleanedText = System.Text.RegularExpressions.Regex.Replace(cleanedText, "(\r\n|\n|\r){2,}", Environment.NewLine)

        ' 移除无效字符
        cleanedText = System.Text.RegularExpressions.Regex.Replace(cleanedText, "[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]", "")

        ' 修复断行问题 - 尝试重建自然段落
        cleanedText = System.Text.RegularExpressions.Regex.Replace(cleanedText, "(?<=[^\.\?\!:;])\r\n(?=[a-zA-Z])", " ")

        Return cleanedText.Trim()
    End Function

    ' 提取关键词
    Public Function ExtractKeywords(content As String) As List(Of String)
        If String.IsNullOrEmpty(content) Then
            Return New List(Of String)()
        End If

        ' 如果内容太长，只处理部分
        Const MaxContentLength As Integer = 50000  ' 50KB
        If content.Length > MaxContentLength Then
            content = content.Substring(0, MaxContentLength / 2) &
                  content.Substring(content.Length - MaxContentLength / 2)
        End If

        ' 简单实现：删除常见停用词，提取高频词
        Dim stopWords As New List(Of String)({"a", "an", "the", "and", "or", "but", "is", "are", "was", "were", "be", "to", "of", "in", "that", "have", "it", "for"})

        ' 分词并转为小写
        Dim words As New List(Of String)()
        Dim wordPattern = "\b\w{3,}\b"  ' 至少3个字符的单词
        'Dim matches = Regex.Matches(content.ToLower(), "\w+")
        Dim matches = Regex.Matches(content.ToLower(), wordPattern)

        ' 计算词频
        Dim wordFreq As New Dictionary(Of String, Integer)()
        'For Each match As Match In matches
        '    Dim word = match.Value
        '    If Not stopWords.Contains(word) Then
        '        If wordFreq.ContainsKey(word) Then
        '            wordFreq(word) += 1
        '        Else
        '            wordFreq.Add(word, 1)
        '        End If
        '    End If
        'Next

        For Each match As Match In matches
            Dim word = match.Value
            If word.Length > 2 AndAlso Not stopWords.Contains(word) Then
                words.Add(word)
            End If
        Next


        For Each word In words
            If wordFreq.ContainsKey(word) Then
                wordFreq(word) += 1
            Else
                wordFreq.Add(word, 1)
            End If
        Next

        ' 选择前20个高频词
        Return wordFreq.OrderByDescending(Function(pair) pair.Value).Take(20).Select(Function(pair) pair.Key).ToList()
    End Function

    ' 清理资源
    Public Sub Dispose()
        _ocrProcessor?.Dispose()
    End Sub
End Class
